/**
 * Copyright  (c) 2009-2013 XLab,  Org. 
 * All  rights  reserved. 
 */
package org.xlab.baseframework.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.hibernate.classic.Validatable;
import org.hibernate.classic.ValidationFailure;
import org.xlab.baseframework.domain.enumerate.EnumDeletedIndentifying;
import org.xlab.baseframework.system.Declare;

/**
 * <p>
 * 系统Code体系使用的实体类
 * </p>
 * 
 * @author MaKuBEX Email:makubexnet@gmail.com
 * @version 1.0.0 Sep 7, 2010
 * @since 1.0.0
 * 
 */
@Entity
@Table(name = "T_SYS_MSTR_CODE")
public class SystemCode extends AbstractLogicalVersionControlDomainObject
		implements Comparable<SystemCode>, Validatable {

	/**
	 * @serialField
	 */
	private static final long serialVersionUID = 2518679646644612987L;

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = Declare.DEFAULT_SYSTEM_DB_SEQUENCE)
	@SequenceGenerator(name = Declare.DEFAULT_SYSTEM_DB_SEQUENCE, sequenceName = Declare.DEFAULT_SYSTEM_DB_SEQUENCE, allocationSize = 1, initialValue = 0)
	@Column(name = "ID_")
	private Long id;

	@Column(name = "CODE_", nullable = false, unique = true, length = 20)
	private String code;

	@ManyToOne(fetch = FetchType.LAZY, targetEntity = SystemCode.class)
	@JoinColumn(name = "CATEGORY_", referencedColumnName = "CODE_", nullable = true)
	private SystemCode category;
	@Column(name = "DESCRIPTION_", length = 2000)
	private String description;
	@Column(name = "SEQUENCE_")
	private Long sequence;
	@Column(name = "CREATED_BY_NAME")
	private String createdByName;
	@Column(name = "LASTUPDATED_BY_NAME")
	private String lastUpdatedByName;
	/**
	 * <p>
	 * 默认构造函数
	 * </p>
	 */
	public SystemCode() {
		super();
	}
	/**
	 * <p>
	 * 完整构造函数
	 * </p>
	 * 
	 * @param code
	 *            代码
	 * @param category
	 *            类别(即父代码)
	 * @param description
	 *            描述
	 * @param sequence
	 *            顺序
	 * @param deletedInd
	 *            是否被删除
	 */
	public SystemCode(String code, SystemCode category, String description,
			Long sequence, EnumDeletedIndentifying deletedInd) {
		super();
		this.code = code;
		this.category = category;
		this.description = description;
		this.sequence = sequence;
		super.deletedInd = deletedInd;
	}

//	@OneToMany(targetEntity = SystemCode.class, fetch = FetchType.LAZY, mappedBy = "category")
//	private Set<SystemCode> subCodes;

	/**
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	public int compareTo(SystemCode o) {
		if (this.category == null && o.getCategory() != null) {
			return 1;
		} else if (this.category != null && o.getCategory() == null) {
			return -1;
		} else if ((this.category == null && o.getCategory() == null)
				|| (this.category.equals(o.getCategory()))) {
			if (this.sequence > o.getSequence()) {
				return 1;
			} else if (this.sequence < o.getSequence()) {
				return -1;
			} else {
				return 0;
			}
		} else {
			if (this.category.getCode().hashCode() > o.getCategory().getCode()
					.hashCode()) {
				return 1;
			} else if (this.category.getCode().hashCode() < o.getCategory()
					.getCode().hashCode()) {
				return -1;
			} else {
				return 0;
			}
		}
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		SystemCode other = (SystemCode) obj;
		if (code == null) {
			if (other.code != null)
				return false;
		} else if (!code.equals(other.code))
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (sequence == null) {
			if (other.sequence != null)
				return false;
		} else if (!sequence.equals(other.sequence))
			return false;
		return true;
	}

	/**
	 * @return the category
	 */
	public SystemCode getCategory() {
		return category;
	}

	/**
	 * @return the code
	 */
	public String getCode() {
		return code;
	}

	/**
	 * @return the createdByName
	 */
	public String getCreatedByName() {
		return createdByName;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @return the lastUpdatedByName
	 */
	public String getLastUpdatedByName() {
		return lastUpdatedByName;
	}

	/**
	 * @return the sequence
	 */
	public Long getSequence() {
		return sequence;
	}

	/**
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((code == null) ? 0 : code.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result
				+ ((sequence == null) ? 0 : sequence.hashCode());
		return result;
	}

	/**
	 * @param category
	 *            the category to set
	 */
	public void setCategory(SystemCode category) {
		this.category = category;
	}

	/**
	 * @param code
	 *            the code to set
	 */
	public void setCode(String code) {
		this.code = code;
	}

	/**
	 * @param createdByName
	 *            the createdByName to set
	 */
	public void setCreatedByName(String createdByName) {
		this.createdByName = createdByName;
	}

	/**
	 * @param description
	 *            the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @param lastUpdatedByName
	 *            the lastUpdatedByName to set
	 */
	public void setLastUpdatedByName(String lastUpdatedByName) {
		this.lastUpdatedByName = lastUpdatedByName;
	}

	/**
	 * @param sequence
	 *            the sequence to set
	 */
	public void setSequence(Long sequence) {
		this.sequence = sequence;
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return "SystemCode [id=" + id + ", code=" + code + ", category="
				+ category + ", description=" + description + ", sequence="
				+ sequence + ", deletedInd=" + deletedInd + ", createdByName="
				+ createdByName + ", lastUpdatedByName=" + lastUpdatedByName
				+ "]";
	}

	/**
	 * @see org.hibernate.classic.Validatable#validate()
	 */
	public void validate() throws ValidationFailure {
		if (this.code == null) {
			throw new ValidationFailure("The property [code] is null.");
		} else if (this.description == null) {
			throw new ValidationFailure("The property [description] is null.");
		}
	}
}
